﻿using MetroDataApi.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Converters;

namespace MetroDataApi.Controllers.DataQueryTable
{

    public class ChangeTableController : Controller
    {
        //
        // GET: /ChangeTable/
        private JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings()
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new MyDateTimeConvertor() }
        };

        public ActionResult Index(int prjId, string names = "", string startTime = "",
            string endTime = "", string monitorType = "", string location = "", string json = "0")
        {
            if (json == "1")
            {
                return RedirectToAction("Get", new
                {
                    action = "Get",
                    prjId = prjId,
                    names = names,
                    startTime = startTime,
                    endTime = endTime,
                    monitorType = monitorType,
                    location = location
                });
            }
            else
            {
                List<string> nameList = names.Split(',').ToList();
                var items = this.Query(prjId, nameList, startTime, endTime);
                ViewBag.Items = items;
                return View();
            }
        }

        //json 实现
        public ContentResult Get(int prjId, string names = "", string startTime = "",
            string endTime = "", string monitorType = "", string location = "")
        {
            using (var db = new MetroDataDataContext())
            {

                var nameList = (names == "") ? (from p in db.MonitorPointsDictionary
                                                where p.PrjId == prjId && p.MonitorType == monitorType &&
                                                    p.Location == location
                                                select p.Name).ToList() : names.Split(',').ToList();
                var items = this.Query(prjId, nameList, startTime, endTime);


                return this.Content(JsonConvert.SerializeObject(items, Formatting.Indented, jsonSerializerSettings), "application/json");
            }
        }

        public ActionResult DataContent(int prjId, string fields = "date,number", string order = "asc", string split = ",", string json = "0")
        {
            //var datas = this.getMonitorPoints(prjId, type);
            if (json == "0")
            {
                var datas = this.getDataContentSummary(prjId, order);
                ViewBag.Datas = datas;
                ViewBag.Type = fields;
                ViewBag.Split = split.Length == 1 ? split : ",";
                ViewBag.Max = datas.Max(p => p.Count);
                return View();
            }
            else
            {
                return
                    RedirectToAction("DataContentJson", new { prjId = prjId, fields = fields, order = order, split = split });
            }

        }


        [HttpGet]
        public ContentResult DataContentJson(int prjId, string fields = "date,number", string order = "asc", string split = ",")
        {
            using (var db = new MetroDataDataContext())
            {
                var datas = this.getDataContentSummary(prjId, order);
                return this.Content(JsonConvert.SerializeObject(datas, Formatting.Indented, jsonSerializerSettings), "application/json");
            }
        }


        /// <summary>
        /// 获取本次,上次,初始值
        /// </summary>
        /// <param name="prjId"></param>
        /// <param name="names"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        private List<IEnumerable<result>> Query(int prjId, List<string> names, string startTime = "", string endTime = "")
        {
            var items = new List<IEnumerable<result>>();
            List<string> times = new List<string>();
            times.Add(startTime); times.Add(endTime);

            if (startTime == "" && endTime == "")
            {
                var ss = new List<string>();
                times = Recent2Changes.GetRecent2Times(prjId, names, out ss);
            }
            else if (endTime != "" && startTime == "")
            {
                times = Recent2Changes.Get2TimesByLastTime(prjId, endTime, names);
            }
            else if (endTime == "" && startTime != "")
            {
                times[1] = DateTime.Now.Date.ToString("yyyy-MM-dd");
                times = Recent2Changes.GetActual2TimesByFuzzyTime(prjId, names, times);
            }
            else
            {
                times = Recent2Changes.GetActual2TimesByFuzzyTime(prjId, names, times);
            }
            times.Add(QueryResults.GetOriginTime(prjId, names[0]));
            times = times.OrderBy(p => DateTime.Parse(p)).ToList();//顺序排列
            var originTime = times[0];

            var origins = QueryResults.GetOriginResults(prjId, names).ToList();


            var reviewTimeList = Recent2Changes.GetRecentReviewedTimeList(prjId, names);
            if (startTime == "" && endTime == "" && reviewTimeList.Count > 0)
            {
                var cur = QueryResults.GetReviewResultsByTime(prjId, reviewTimeList[0], names);
                var last = QueryResults.GetResultsByTime(prjId, times[2], names).ToList();

                cur = (from o in origins
                       from p in cur.ToList().Where(p => p.name == o.name).DefaultIfEmpty()
                       select p).ToList();

                last = (from o in origins
                        from p in last.Where(p => p.name == o.name).DefaultIfEmpty()
                        select p).ToList();

                items.Add(origins);
                items.Add(last);
                items.Add(cur);
            }
            else
            {
                var cur = QueryResults.GetResultsByTime(prjId, times[2], names).ToList();

                cur = (from o in origins
                       from p in cur.Where(p => p.name == o.name).DefaultIfEmpty()
                       select p).ToList();

                var last = QueryResults.GetResultsByTime(prjId, times[1], names).ToList();
                last = (from o in origins
                        from p in last.Where(p => p.name == o.name).DefaultIfEmpty()
                        select p).ToList();
                items.Add(origins);
                items.Add(last);
                items.Add(cur);
            }




            return items;
        }



        private List<DataContent> getDataPreviewContentSummary(int prjId, string order = "asc")
        {
            using (var db = new MetroDataDataContext())
            {
                List<DataContent> aa = new List<DataContent>();
                if (order == "asc")
                {
                    var aaa = from f in
                                  (from m in
                                       (from p in db.PreReviewMonitorPoints
                                        from q in db.MonitorPointsDictionary
                                        where p.Name == q.Name && p.PrjId == prjId && q.PrjId == prjId
                                        group p by new { p.DateTime.Value, q.MonitorType, q.Location } into g
                                        orderby g.Key.Value ascending
                                        select new
                                        {
                                            g.Key,
                                            g,
                                            g.ToList().Count
                                        })
                                   group m by new { m.Key.Location, m.Key.MonitorType } into mg
                                   select mg)
                              orderby f.Key.MonitorType, f.Key.Location
                              select new DataContent(f.Key.MonitorType, f.Key.Location)
                              {
                                  Items = f.Select(p =>
                                     new DataContentItem() { Count = p.Count, Date = p.Key.Value }).ToList()
                              };
                    aa = aaa.ToList();
                    return aaa.ToList();
                }
                else
                {
                    aa.Reverse();
                }
                return aa;
            }

        }


        private List<DataContent> getDataContentSummary(int prjId, string order = "asc")
        {
            using (var db = new MetroDataDataContext())
            {
                var pts = from p in db.MonitorPoints where p.PrjId == prjId select p;
                var ptList = from t in db.PreReviewMonitorPoints.Where(p => p.PrjId == prjId).Select(p => new
                {
                    DateTime = p.DateTime,
                    Name = p.Name,
                    PrjId = p.PrjId,
                    Value = p.Value
                }).Union(db.MonitorPoints.Where(p => p.PrjId == prjId).Select(p => new
                {
                    DateTime = p.DateTime,
                    Name = p.Name,
                    PrjId = p.PrjId,
                    Value = p.Value
                }))
                             select t;

                if (order == "asc")
                {

                    var aaa = from f in
                                  (from m in
                                       (from p in ptList
                                        from q in db.MonitorPointsDictionary
                                        where p.Name == q.Name && p.PrjId == prjId && q.PrjId == prjId
                                        group p by new { p.DateTime.Value, q.MonitorType, q.Location } into g
                                        orderby g.Key.Value ascending
                                        select new
                                        {
                                            g.Key,
                                            g,
                                            g.ToList().Count
                                        })
                                   group m by new { m.Key.Location, m.Key.MonitorType } into mg
                                   select mg)
                              orderby f.Key.MonitorType, f.Key.Location
                              select new DataContent(f.Key.MonitorType, f.Key.Location)
                              {
                                  Items = f.Select(p =>
                                     new DataContentItem() { Count = p.Count, Date = p.Key.Value }).ToList()
                              };

                    return aaa.ToList();
                }
                else
                {
                    var aaa = from f in
                                  (from m in
                                       (from p in ptList
                                        from q in db.MonitorPointsDictionary
                                        where p.Name == q.Name && p.PrjId == prjId && q.PrjId == prjId
                                        group p by new { p.DateTime.Value, q.MonitorType, q.Location } into g
                                        orderby g.Key.Value descending
                                        select new
                                        {
                                            g.Key,
                                            g,
                                            g.ToList().Count
                                        })
                                   group m by new { m.Key.Location, m.Key.MonitorType } into mg
                                   select mg)
                              orderby f.Key.MonitorType, f.Key.Location
                              select new DataContent(f.Key.MonitorType, f.Key.Location)
                              {
                                  Items = f.Select(p =>
                                      new DataContentItem() { Count = p.Count, Date = p.Key.Value }).ToList()
                              };

                    return aaa.ToList();
                }
            }
        }

    }


}
